#!/bin/bash
###
# @Author: 以谁为师
# @Website: attacker.club
# @Date: 2020-08-05 10:40:47
# @LastEditTime: 2024-08-29 00:15:53
# @Description: Internet initialization scripts

#  curl -sL http://wuyou.run/scripts/system/centos7/init.sh |bash -s k8s-1

# -----------  打印颜色 ----------- #
function print_msg() {
    case "$1" in
    "error" | "red")
        echo -e "\e[1;31m$2\e[0m"
        ;;
    "warn" | "yellow")
        echo -e "\e[1;33m$2\e[0m"
        ;;
    "info" | "blue")
        echo -e "\e[1;34m$2\e[0m"
        ;;
    "success" | "green")
        echo -e "\e[1;32m$2\e[0m"
        ;;
    esac
}

source /etc/os-release

# 针对云平台Linux 2.1903 LTS (Hunting Beagle)的初始化步骤
init_cloud_linux2() {
    echo "这是云平台Linux 2.1903 LTS (Hunting Beagle)"
    pre_check
    Set_dns
    Set_ntp
    Yum_update_pkg
    Set_hostname
    Set_Selinux
    Set_iptables
    Set_virtual
    Set_ssh
    Set_limits
    Set_profile
    Set_timezone
    Set_swap
    Optimize_kernel
}

# 针对CentOS 初始化步骤
init_centos() {
    echo "这是CentOS"
    pre_check
    Set_dns
    Set_ntp
    Yum_update_pkg
    Set_hostname
    Set_Selinux
    Set_iptables
    Set_virtual
    Set_ssh
    Set_limits
    Set_profile
    Set_timezone
    Set_swap
    Optimize_kernel
}

# 针对Ubuntu的初始化步骤
init_ubuntu() {
    echo "这是Ubuntu"
    pre_check
    Set_dns
    Set_ntp
    Apt_update_pkg
    Set_hostname
    Set_Ubuntu_firewall
    Set_ssh
    Set_limits
    Set_profile
    Set_timezone
    Set_swap
    Optimize_kernel
}
pre_check() {

    if [ $(id -u) -ne 0 ]; then
        print_msg "warn" ">> This script must be run as root !!!"
        exit 0
    fi
}

Yum_update_pkg() {

    curl -s https://mirrors.aliyun.com/repo/epel-7.repo >/etc/yum.repos.d/epel-7.repo
    curl -s https://mirrors.aliyun.com/repo/Centos-7.repo >/etc/yum.repos.d/Centos-7.repo

    yum --debuglevel=1 install gcc gcc-c++ openssl-devel nfs-utils libtool \
        openssl-perl ncurses-devel pcre-devel zlib zlib-devel unzip nmap iotop sysstat dstat iftop nload iperf iproute net-tools \
        lrzsz wget mlocate lsof telnet yum-utils dmidecode -y
}

Apt_update_pkg() {
    apt update
    apt install -y gcc g++ libssl-dev nfs-common libtool \
        libssl-dev libncurses5-dev libpcre3 zlib1g-dev unzip nmap iotop sysstat dstat iftop iperf iproute2 net-tools \
        lrzsz wget mlocate lsof telnet software-properties-common
}

Set_hostname() {

    # bash host_init.sh hostname 主机名传参
    if [ $# -lt 1 ]; then
        #传参少于1个
        print_msg "warn" "---- Use default options  ----"
        HOSTNAME="TemplateOS"
        # 默认主机名TemplateOS
    else
        print_msg "info" "---- Set  Hostname ----"
        HOSTNAME=$1
    fi

    if [ -f /etc/hostname ]; then
        echo "$HOSTNAME" >/etc/hostname
    fi
    sed -i "/HOSTNAME/c HOSTNAME=$HOSTNAME" /etc/sysconfig/network || echo "HOSTNAME=$HOSTNAME" >>/etc/sysconfig/network
    hostname $HOSTNAME
    grep $HOSTNAME /etc/hosts || echo "127.0.0.1 $HOSTNAME" >>/etc/hosts
}

Set_Selinux() {
    print_msg "info" "---- close  selinux ----"
    if [ -s /etc/selinux/config ]; then
        setenforce 0
        sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
    fi
}

Set_iptables() {
    print_msg "info" "---- setup iptables ----"
    if [ ! -f /etc/sysconfig/iptables ]; then
        yum install iptables-services -y
        chkconfig iptables on
        systemctl enable iptables
        systemctl disable firewalld
        systemctl stop firewalld
        service iptables restart
    fi

    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
    iptables-save &>/dev/null
    service iptables save &>/dev/null
}

Set_virtual() {
    print_msg "info" "---- virtual machine setting  ----"
    virtual=$(dmesg | grep -i virtual | grep input | wc -l)
    if [ $virtual = 0 ]; then
        print_msg "info" "---- physical machine setting ----"
        hwclock -w                                              # 将系统时钟同步到硬件时钟
        sed -i '/bell-style/c set bell-style none' /etc/inputrc # 替换禁止滴滴声
        # dmidecode -s system-product-name|awk '{if($1!~"VMware")exit 1}' || hwclock -w
    fi
}

Set_dns() {
    print_msg "info" "---- Start configuring  DNS ----"
    ping -c1 baidu.com &>/dev/null || echo "nameserver 223.5.5.5" >>/etc/resolv.conf
    # 如果dns无法解析添加一条dns
}

Set_ntp() {
    print_msg "---- info" "Start configuring  NTP ----"
    # 检查 ntpdate 是否安装
    if ! command -v ntpdate &>/dev/null; then
        # 如果没有 ntpdate，检查 chrony 是否安装，如果没有一起安装
        if ! command -v chronyd &>/dev/null; then
            if [ -x "$(command -v yum)" ]; then
                yum --debuglevel=1 install chrony ntpdate -y
                echo "使用 yum 安装 chrony 和 ntpdate。"
            elif [ -x "$(command -v apt)" ]; then
                apt update
                apt install -y chrony ntpdate
                echo "使用 apt 安装 chrony 和 ntpdate。"
            else
                echo "既没有找到 yum 也没有找到 apt。无法安装 chrony 和 ntpdate。"
            fi
        else
            # 如果 chrony 已安装，只安装 ntpdate
            if [ -x "$(command -v yum)" ]; then
                yum --debuglevel=1 install ntpdate -y
                echo "使用 yum 安装 ntpdate。"
            elif [ -x "$(command -v apt)" ]; then
                apt update
                apt install -y ntpdate
                echo "使用 apt 安装 ntpdate。"
            else
                echo "既没有找到 yum 也没有找到 apt。无法安装 ntpdate。"
            fi
        fi
    else
        # 如果 ntpdate 已安装，检查 chrony 是否安装，如果没有安装 chrony
        if ! command -v chronyd &>/dev/null; then
            if [ -x "$(command -v yum)" ]; then
                yum --debuglevel=1 install chrony -y
                echo "使用 yum 安装 chrony。"
            elif [ -x "$(command -v apt)" ]; then
                apt update
                apt install -y chrony
                echo "使用 apt 安装 chrony。"
            else
                echo "既没有找到 yum 也没有找到 apt。无法安装 chrony。"
            fi
        else
            echo "ntpdate 和 chrony 都已安装。"
        fi
    fi

    cat >/etc/chrony.conf <<EOF
server ntp.aliyun.com prefer iburst
server time1.cloud.tencent.com iburst
server 0.amazon.pool.ntp.org iburst
# 阿里、腾讯、aws授时服务器；prefer表示为优先

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
local stratum 10
# 即使server指令中时间服务器不可用，也允许将本地时间作为标准时间授时给其它客户端
EOF
    systemctl enable chronyd && systemctl restart chronyd
    chronyc sources # 检查时间同步
    if ! command -v ntpdate &>/dev/null; then
        ntpdate
    fi
    ntpdate ntp.aliyun.com
}

Set_timezone() {
    print_msg "info" "---- Start configuring  Timezone ---- "
    \cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &>/dev/null
    timedatectl set-timezone "Asia/Shanghai"
    print_msg "warn" "当前时区为: Asia/Shanghai"
}

Set_ssh() {
    print_msg "info" "---- Start configuring  SSH optimize---- "
    # sed -i '/^#Port/c Port 6022' /etc/ssh/sshd_config &>/dev/null # 默认端口修改
    grep '#UseDNS yes' /etc/ssh/sshd_config && sed -i "s/#UseDNS yes/UseDNS no/g" /etc/ssh/sshd_config
    grep '#AuthorizedKeysFile' /etc/ssh/sshd_config && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/" /etc/ssh/sshd_config
    grep 'GSSAPIAuthentication yes' /etc/ssh/sshd_config && sed -i "s/GSSAPIAuthentication yes/GSSAPIAuthentication no/g" /etc/ssh/sshd_config
    systemctl restart sshd # sshd服务重启
}

Set_limits() {
    print_msg "info" "---- Start configuring  System limits ---- "
    chmod +x /etc/rc.local
    grep ulimit /etc/rc.local || echo ulimit -HSn 1048576 >>/etc/rc.local

    grep 1048576 /etc/security/limits.conf || cat >>/etc/security/limits.conf <<EOF
* soft nproc 1048576
* hard nproc 1048576
* soft nofile 1048576
* hard nofile 1048576
* soft stack 1048575
EOF
    grep 1048576 /etc/security/limits.d/20-nproc.conf || cat /etc/security/limits.d/20-nproc.conf <<EOF
*          soft    nproc     1048575
root       soft    nproc     unlimited
EOF
}

Set_profile() {
    print_msg "info" "---- Start configuring  /etc/profile ---- "
    # grep vi ~/.bashrc || sed -i "/mv/a\alias vi='vim'" ~/.bashrc
    grep PS /etc/profile || echo '''PS1="\[\e[37;1m\][\[\e[32;1m\]\u\[\e[37;40m\]@\[\e[34;1m\]\h \[\e[0m\]\t \[\e[35;1m\]\W\[\e[37;1m\]]\[\e[m\]/\\$" ''' >>/etc/profile
    grep HISTTIMEFORMAT /etc/profile || cat >>/etc/profile <<EOF
export HISTTIMEFORMAT="%F %T \$(whoami) " 
export HISTSIZE=10000
EOF
}

Set_swap() {
    print_msg "info" "---- stop swap ---- "
    swapoff -a                  # 临时关闭swap
    sed -i '/swap/d' /etc/fstab # 永久关闭swap
}

Optimize_kernel() {
    print_msg "info" "---- Kernel parameter optimize /etc/sysctl.conf ----"

    grep 65535 /etc/sysctl.conf || cat >/etc/sysctl.conf <<EOF
fs.file-max = 9999999
# 所有进程最大的文件数
fs.nr_open = 9999999
# 单个进程可分配的最大文件数
fs.aio-max-nr = 1048576
# 1024K；同时可以拥有的的异步IO请求数目

fs.inotify.max_queued_events = 327679
#  文件队列长度限制
fs.inotify.max_user_instances = 65535
#  每个real user ID可创建的inotify instatnces的数量上限，默认128.
fs.inotify.max_user_watches = 99999999
# 注册监听目录的数量限制

net.ipv4.ip_local_port_range = 9000 65000
# 被动端口范围

net.ipv4.tcp_keepalive_time = 180
# 客户端每次发送心跳的周期，默认值为7200s（2小时）；检测服务端是否活着
net.ipv4.tcp_keepalive_intvl = 15
# 探测包的发送间隔 默认75秒
net.ipv4.tcp_keepalive_probes = 5
# 没有接收到对方确认，继续发送保活探测包次数 默认9次

net.ipv4.tcp_tw_reuse = 1
#启用tcp重用
net.ipv4.tcp_fin_timeout = 3
# 决定FIN-WAIT-2状态的时间
net.ipv4.tcp_tw_recycle = 0
# TIME-WAIT的tcp快速回收；入口网关禁用此项

net.core.somaxconn = 8192
#监听队列的长度
net.netfilter.nf_conntrack_max = 262144
# 网络并发连接数等限制
net.nf_conntrack_max = 262144
# 网络并发连接数等限制

# vm.nr_hugepages=512 # 内核大页内存
# net.core.somaxconn = 65535 # 端口最大监听队列长度
# net.ipv4.tcp_max_syn_backlog  # SYN同步包的最大客户端数量

net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
#禁止数据包重定向发送 (安全)

# kernel.shmall = 2097152
# kernel.shmmax = 1073741824
# kernel.shmmni = 4096
# kernel.sem = 250 32000 100 128
# net.core.rmem_default = 262144
# net.core.rmem_max = 4194304
# net.core.wmem_default = 262144
# net.core.wmem_max = 1048576

kernel.pid_max=655350
vm.max_map_count=262144
EOF
    sysctl -p
    cat >/etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
    sysctl --system # 生效

}

# 根据系统类型执行初始化
if [[ $ID == "alinux" && $VERSION_ID == "2.1903" ]]; then
    init_alinux
elif [[ $ID == "centos" && $VERSION_ID == "7" ]]; then
    init_centos
elif [[ $ID == "ubuntu" ]]; then
    init_ubuntu
fi

print_msg "success" ">> 脚本执行结束... "
